package ctrler

import (
	"strings"
	"webgo/server/plugin"
	"webgo/server/storage"

	"github.com/gin-gonic/gin"
)

type AccountType struct {
	Type[struct {
		AdminPassword string `env:"ADMIN_PASSWORD"`
	}]
}

func MyAccount(ctx *gin.Context) (account *storage.AccountUnitType) {

	if value, ok := ctx.Get("my_account"); ok {
		account, _ = value.(*storage.AccountUnitType)
	}

	return
}

func (_self *AccountType) Init() (err error) {

	var (
		admin = storage.Account.ExistedByName("admin")
	)

	if admin == nil {

		admin = &storage.AccountUnitType{}

		admin.Static.Nick = "管理员"
		admin.Static.Username = "admin"
		admin.Static.Password = _self.config.AdminPassword

		if err = storage.Account.Insert(nil, admin); err != nil {
			return
		}
	}

	if admin.Static.Password != _self.config.AdminPassword {

		if err = storage.Account.Update(nil, admin.Id, func(static *storage.AccountStaticType) {
			static.Password = _self.config.AdminPassword
		}, nil); err != nil {
			return
		}
	}

	return
}

func (_self *AccountType) Auth() gin.HandlerFunc {

	return func(ctx *gin.Context) {

		var (
			authorization = ctx.GetHeader("authorization")
		)

		if id, update_time, ok := plugin.Httpserver.TokenParse(authorization); !ok {

		} else if account := storage.Account.Existed(nil, id); account == nil {

		} else if account.UpdateTime.Static != update_time {

		} else {
			ctx.Set("my_account", account)
			ctx.Next()
			return
		}

		ctx.Abort()
	}
}

func (_self *AccountType) Login(ctx *gin.Context) {

	var (
		table storage.AccountStaticType
	)

	if err := ctx.Bind(&table); err != nil {
		plugin.HttpResponse(ctx, plugin.HTTP_RESPONSE_CODE.ERROR, "格式错误", err.Error())
		return
	}

	var (
		account = storage.Account.ExistedByName(table.Username)
	)

	if account == nil {
		plugin.HttpResponse(ctx, plugin.HTTP_RESPONSE_CODE.FAIL, "账号不存在", nil)
		return
	}

	if account.Static.Password != table.Password {
		plugin.HttpResponse(ctx, plugin.HTTP_RESPONSE_CODE.FAIL, "密码错误", nil)
		return
	}

	if token, err := plugin.Httpserver.TokenCompose(account.Id, account.UpdateTime.Static); err != nil {
		plugin.HttpResponse(ctx, plugin.HTTP_RESPONSE_CODE.ERROR, "请求失败", err.Error())
		return

	} else {
		plugin.HttpResponse(ctx, plugin.HTTP_RESPONSE_CODE.SUCCESS, "登录成功", map[string]any{
			"token":    token,
			"username": account.Static.Username,
		})
	}
}

func (_self *AccountType) Renew(ctx *gin.Context) {

	var (
		my_account = MyAccount(ctx)
	)

	if token, err := plugin.Httpserver.TokenCompose(my_account.Id, my_account.UpdateTime.Static); err != nil {
		plugin.HttpResponse(ctx, plugin.HTTP_RESPONSE_CODE.ERROR, "请求", err.Error())
		return

	} else {
		plugin.HttpResponse(ctx, plugin.HTTP_RESPONSE_CODE.SUCCESS, "登录成功", map[string]any{
			"token":    token,
			"username": my_account.Static.Username,
		})
	}
}

func (_self *AccountType) Create(ctx *gin.Context) {

	var (
		my_account = MyAccount(ctx)

		table storage.AccountUnitType
	)

	if my_account.Static.Username != "admin" {
		plugin.HttpResponse(ctx, plugin.HTTP_RESPONSE_CODE.FAIL, "无操作权限", nil)
		return
	}

	if err := ctx.Bind(&table.Static); err != nil {
		plugin.HttpResponse(ctx, plugin.HTTP_RESPONSE_CODE.ERROR, "格式错误", err.Error())
		return
	}

	if len(table.Static.Nick) == 0 || len(table.Static.Username) == 0 || len(table.Static.Password) == 0 {
		plugin.HttpResponse(ctx, plugin.HTTP_RESPONSE_CODE.FAIL, "不能为空", nil)
		return
	}

	if strings.Contains(table.Static.Nick+table.Static.Username+table.Static.Password, " ") {
		plugin.HttpResponse(ctx, plugin.HTTP_RESPONSE_CODE.FAIL, "不能包含空格", nil)
		return
	}

	if storage.Account.ExistedByName(table.Static.Username) != nil {
		plugin.HttpResponse(ctx, plugin.HTTP_RESPONSE_CODE.FAIL, "用户名已存在", nil)
		return
	}

	if err := storage.Account.Insert(nil, &table); err != nil {
		plugin.HttpResponse(ctx, plugin.HTTP_RESPONSE_CODE.ERROR, "请求失败", err.Error())
		return
	}

	plugin.HttpResponse(ctx, plugin.HTTP_RESPONSE_CODE.SUCCESS, "创建成功", nil)
}

func (_self *AccountType) Delete(ctx *gin.Context) {

	var (
		my_account = MyAccount(ctx)

		params struct {
			Id string `form:"id" json:"id"`
		}
	)

	if my_account.Static.Username != "admin" {
		plugin.HttpResponse(ctx, plugin.HTTP_RESPONSE_CODE.FAIL, "无操作权限", nil)
		return
	}

	if err := ctx.BindQuery(&params); err != nil {
		plugin.HttpResponse(ctx, plugin.HTTP_RESPONSE_CODE.ERROR, "格式错误", err.Error())
		return
	}

	var (
		account_id = plugin.MongoObjectIdString(params.Id)
		account    = storage.Account.Existed(nil, account_id)
	)

	if account == nil {
		plugin.HttpResponse(ctx, plugin.HTTP_RESPONSE_CODE.FAIL, "账号不存在", nil)
		return
	}

	if err := storage.Account.Delete(nil, account.Id); err != nil {
		plugin.HttpResponse(ctx, plugin.HTTP_RESPONSE_CODE.ERROR, "请求失败", err.Error())
		return
	}

	plugin.HttpResponse(ctx, plugin.HTTP_RESPONSE_CODE.SUCCESS, "删除成功", nil)
}

func (_self *AccountType) SyncUpdate(ctx *gin.Context) {

	var (
		my_account  = MyAccount(ctx)
		update_time = storage.UpdateTimeType{}
	)

	if err := ctx.BindQuery(&update_time); err != nil {
		plugin.HttpResponse(ctx, plugin.HTTP_RESPONSE_CODE.ERROR, "格式错误", err.Error())
		return
	}

	if my_account.Static.Username == "admin" {
		plugin.HttpResponse(ctx, plugin.HTTP_RESPONSE_CODE.SUCCESS, "", storage.SyncUpdate(nil, &update_time))
	} else {
		plugin.HttpResponse(ctx, plugin.HTTP_RESPONSE_CODE.SUCCESS, "", storage.SyncUpdate(&my_account.Id, &update_time))
	}

}
